<template>
	<div>
		<div class="upload">
			<div v-for="(item, index) in imageList" :key="index" class="uploadImg">
				<img class="thumbnail" :src="item.url" alt="" />
				<div class="shadow">
					<div class="icon" @click="handlePictureCardPreview(item, index)">
						<i class="el-icon-zoom-in up"></i>
					</div>
					<div class="icon" @click="handleRemove(item, index)">
						<i class="el-icon-delete up"></i>
					</div>
				</div>
			</div>
			<el-upload
				v-if="couldUpload"
				ref="elUploadRef"
				:accept="accept"
				:action="fileUploadUrl"
				:auto-upload="false"
				:on-change="imageChange"
				:multiple="multiple"
				:list-type="type"
				:drag="drag"
				:limit="limit"
				:show-file-list="false"
			>
				<i class="el-icon-plus"></i>
			</el-upload>
		</div>
		<div class="tip">
			请上传
			<span>图片</span>
			格式文件 ，且文件大小不超过
			<span>{{ size }}</span>
			MB
			<span>{{ tip }}</span>
		</div>
		<v-cropper
			:autoCropWidth="autoCropWidth"
			:autoCropHeight="autoCropHeight"
			:fixedBox="fixedBox"
			:fixed="fixed"
			:round="round"
			:previewWidth="previewWidth"
			:canMoveBox="canMoveBox"
			ref="cropper"
			@success="handleAvatarSuccess"
			:size="size"
			:mode="mode"
			:maxImgSize="maxImgSize"
			:enlarge="enlarge"
			:centerBox="centerBox"
		></v-cropper>
		<div v-if="type == 'video'"></div>
		<el-image-viewer
			style="z-index: 9999"
			v-if="visible"
			:url-list="urls"
			:fixedNumber="fixedNumber"
			:outputType="outputType"
			:initial-index="initialIndex"
			teleported
			hide-on-click-modal
			:on-close="onClose"
		></el-image-viewer>
	</div>
</template>
<script setup>
import VCropper from "../cropper/index.vue"

// "el-image-viewer": () => import("element-ui/packages/image/src/image-viewer"),

const props = defineProps({
	type: {
		type: String,
		default: "picture-card",
	},
	// 上传图片限制个数
	limit: {
		type: Number,
		default: 1,
	},
	modelValue: {
		type: [String, Array],
		default: "",
	},
	// 是否多选
	multiple: {
		type: Boolean,
		default: false,
	},
	// 是否拖拽
	drag: {
		type: Boolean,
		default: false,
	},
	// 上传文件类型
	accept: {
		type: String,
		default: "",
	},
	// 默认生成截图框宽度
	autoCropWidth: {
		type: Number,
		default: 200,
	},
	// 默认生成截图框高度
	autoCropHeight: {
		type: Number,
		default: 200,
	},
	//固定截图框大小[宽，高]，默认不允许改变
	fixedBox: {
		type: Boolean,
		default: false,
	},
	//是否开启截图框宽高固定比例
	fixed: {
		type: Boolean,
		default: true,
	},
	// 预览的图片是圆形还是方形
	round: {
		type: Boolean,
		default: false,
	},
	// 预览宽度
	previewWidth: {
		type: Number,
		default: 150,
	},
	// 截图框的宽高比例
	fixedNumber: {
		type: Array,
		default: () => [1, 1],
	},
	outputType: {
		type: String,
		default: "png",
	},
	// 上传的文件大小限制
	size: {
		type: Number,
		default: 3,
	},
	//截图框能否拖动
	canMoveBox: {
		type: Boolean,
		default: true,
	},
	//图片默认渲染方式
	mode: {
		type: String,
		default: "contain",
	},
	// 上传图片最大宽度和高度
	maxImgSize: {
		type: Number,
		default: 2000,
	},
	enlarge: {
		type: Number,
		default: 1,
	},
	tip: {
		type: String,
		default: "",
	},
	// 截图框是否被限制在图片里面
	centerBox: {
		type: Boolean,
		default: true,
	},
})

const emits = defineEmits(["update:modelValue"])

const fileUploadUrl = ref("http://192.168.5.110:8081/system/oss/upload")

const fileList = ref([])
const visible = ref(false)
const disabled = ref(false)
const fileUrl = ref("")
const imageList = ref([])
const initialIndex = ref(0)
const urls = ref([])
const couldUpload = ref(true)
const cropper = ref("")
const elUploadRef = ref("")

function urlsChange() {
	urls.value = imageList.value.map(item => item.url)
}
function couldUploadChange() {
	if (disabled.value) {
		couldUpload.value = false
	} else if (props.limit == -1) {
		couldUpload.value = true
	} else {
		couldUpload.value = imageList.value.length < props.limit
	}
}
function handleCrop(file) {
	nextTick(() => {
		cropper.value.handleChangeUpload(file)
	})
}
function imageChange(file) {
	handleCrop(file)
	elUploadRef.value.clearFiles()
}
function fileChange(file, fileList) {
	fileList.value = fileList.slice(-3)
	// this.$emit("input", fileList)
}
function handlePictureCardPreview(item, index) {
	initialIndex.value = index
	visible.value = true
}
function handleRemove(item, index) {
	imageList.value.splice(index, 1)
	couldUploadChange()
	emit("update:modelVaue", imageList.value.join(","))
}
function handleAvatarSuccess(res) {
	if (res && res.code == 0) {
		nextTick(() => {
			imageList.value = imageList.value.concat([res.data])
			urlsChange()
			couldUploadChange()
		})
		if (Array.isArray(props.modelValue)) {
			emit("update:modelVaue", imageList.value.join(","))
		} else {
			emit("update:modelVaue", res.data.url)
		}
	}
}

function onClose() {
	visible.value = false
}

watch(
	() => props.modelValue,
	val => {
		if (val) {
			if (Array.isArray(val)) {
				imageList.value = val.map(item => {
					if (typeof item == "string") {
						return {
							url: item,
						}
					}
					return item
				})
			} else {
				imageList.value = [
					{
						url: val,
					},
				]
			}
		} else {
			imageList.value = []
		}
	},
	{
		immediate: true,
	}
)
watch(
	() => imageList.value,
	val => {
		if (val) {
			urlsChange()
			couldUploadChange()
		}
	},
	{
		immediate: true,
		deep: true,
	}
)
watch(
	() => props.type,
	val => {
		if (val === "text") {
			drag.value = true
		}
	},
	{
		immediate: true,
	}
)
</script>
<style lang="scss" scoped>
.upload {
	display: flex;
	flex-wrap: wrap;
	.uploadImg {
		position: relative;
		width: 148px;
		height: 148px;
		margin-right: 10px;
		margin-bottom: 10px;
		border-radius: 10px;
		overflow: hidden;
		.thumbnail {
			cursor: pointer;
			width: 100%;
			height: 100%;
			object-fit: cover;
		}
		.shadow {
			display: none;
			position: absolute;
			top: 0;
			left: 0;
			width: 100%;
			height: 100%;
			display: flex;
			justify-content: center;
			align-items: center;
			z-index: 9;
			gap: 25px;
			.icon {
				display: none;
				cursor: pointer;
				color: #fff;
				.up {
					display: none;
					font-size: 20px;
				}
			}
		}
		&:hover {
			.thumbnail {
				cursor: pointer;
				width: 100%;
				object-fit: cover;
			}
			.shadow {
				display: block;
				position: absolute;
				top: 0;
				left: 0;
				width: 100%;
				height: 100%;
				background-color: rgba(0, 0, 0, 0.6);
				display: flex;
				justify-content: center;
				align-items: center;
				z-index: 9;
				gap: 25px;
				.icon {
					display: block;
					cursor: pointer;
					color: #fff;
					.up {
						display: block;
						font-size: 20px;
					}
				}
			}
		}
	}
}
.tip {
	font-size: 12px;
	span {
		color: rgb(245, 108, 108);
		&:last-child {
			color: #787a7d;
		}
	}
}
</style>
